package net.fdukedom.epicurus.domain.util;

import net.fdukedom.epicurus.tools.logging.Logger;
import net.fdukedom.epicurus.tools.logging.WriterId;

import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * This is an utility class to get data source from the context.
 *
 * @author Dmitry Y. Kochelaev
 */
public final class DataSourceHelper {

    /**
     * Datasource name.
     */
    public static final String DATA_SOURCE_NAME = "java:/EpicurusDS";

    private Logger logger = Logger.getInstance(WriterId.DOMAIN);

    /**
     * Application context.
     */
    private Context context;

    /**
     * The only instance of the class.
     */
    private static final DataSourceHelper instance = new DataSourceHelper();

    /**
     * Default constructor.
     */
    private DataSourceHelper() {
        //this is an utility class only one instance is allowed
    }

    /**
     * Returns the only instance of the class.
     *
     * @return the only instance of the class
     */
    public static DataSourceHelper getInstance() {
        return instance;
    }

    /**
     * Looks up for data source in the context.
     *
     * @return data source
     * *
     * @throws NamingException if a naming exception is encountered
     */
    public DataSource getDataSource() throws NamingException {
        logger.logWarning("Manual datasource lookup");
        return (DataSource) getContext().lookup("java:/EpicurusDS");
    }

    /**
     * Returns connection to epicurus datasource.
     *
     * @return connection to epicurus datasource.
     *
     * @throws NamingException if a naming exception is encountered while looking up for data source
     * @throws SQLException if an SQL exception is encountered while creating connection
     */
    public Connection getConnection() throws NamingException, SQLException {
        logger.logWarning("Manual connection lookup");
        Connection connection = instance.getDataSource().getConnection();
        connection.setAutoCommit(true);
        return connection;
    }

    /**
     * Returns intial context.
     *
     * @return intial context
     *
     * @throws NamingException if a naming exception is encountered
     */
    private Context getContext() throws NamingException {
        if (context == null) {
            context = new InitialContext();
        }
        return context;
    }
}
